package org.jeecg.modules.cosmetic.handler;

import cn.hutool.core.util.ObjectUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.compress.utils.Lists;
import org.jeecg.common.api.vo.Result;
import org.jeecg.common.exception.JeecgBootException;
import org.jeecg.modules.cosmetic.constant.enums.IsDeleteEnum;
import org.jeecg.modules.cosmetic.constant.enums.ReferencesEnum;
import org.jeecg.modules.cosmetic.entity.TMaterialLinked;
import org.jeecg.modules.cosmetic.entity.TProductMaterial;
import org.jeecg.modules.cosmetic.model.dto.ProductMaterialDTO;
import org.jeecg.modules.cosmetic.model.vo.ProductMaterialEditorVO;
import org.jeecg.modules.cosmetic.service.ITMaterialLinkedService;
import org.jeecg.modules.cosmetic.service.ITProductMaterialService;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

import javax.annotation.Resource;
import java.util.Comparator;
import java.util.List;
import java.util.Optional;
import java.util.stream.Collectors;

/**
 * @author scx
 * @date 2022/7/18 3:16 下午
 */
@Service
@Slf4j
public class ProductMaterialHandler {

    @Resource
    private ITProductMaterialService productMaterialService;
    @Resource
    private ITMaterialLinkedService materialLinkedService;

    /**
     * 产品关联资料列表查询
     *
     * @param productId
     * @param type
     * @return
     */
    public Result<List<ProductMaterialDTO>> queryProductMaterialList(Long productId, Integer type) {
        LambdaQueryWrapper<TProductMaterial> queryWrapper = new LambdaQueryWrapper<TProductMaterial>()
                .eq(TProductMaterial::getType, type)
                .eq(TProductMaterial::getStatus, IsDeleteEnum.NORMAL.getCode())
                .eq(TProductMaterial::getProductId, productId);
        if (type == ReferencesEnum.DOC.getType()) {
            queryWrapper.or().isNull(TProductMaterial::getProductId);
        }
        List<TProductMaterial> productMaterials = productMaterialService.list(queryWrapper);
        if (CollectionUtils.isEmpty(productMaterials)) {
            log.error("没有关联相关资料，产品主键:{}", productId);
            return Result.ok(Lists.newArrayList());
        }
        int maxNum = productMaterials.stream().mapToInt(TProductMaterial::getIdxNum).max().orElse(0);
        return Result.OK(productMaterials.stream().map(m -> {
            ProductMaterialDTO productMaterialDTO = new ProductMaterialDTO();
            BeanUtils.copyProperties(m, productMaterialDTO);
            if (m.getProductId() == null) {
                productMaterialDTO.setIdxNum(maxNum + 1);
            }
            return productMaterialDTO;
        }).sorted(Comparator.comparing(ProductMaterialDTO::getIdxNum)).collect(Collectors.toList()));
    }

    /**
     * 编辑产品资料信息
     * 增加、修改
     *
     * @param productMaterialEditorVO
     * @return
     */
    public Result<?> editorMaterial(ProductMaterialEditorVO productMaterialEditorVO) {
        TProductMaterial productMaterial = new TProductMaterial();
        productMaterial.setId(productMaterialEditorVO.getId());
        productMaterial.setProductId(productMaterialEditorVO.getProductId());
        productMaterial.setName(productMaterialEditorVO.getName());
        productMaterial.setType(productMaterialEditorVO.getType());
        if (productMaterialEditorVO.getId() != null) {
            productMaterialService.updateById(productMaterial);
            return Result.OK();
        }

        int idxNum = 1;
        if (productMaterialEditorVO.getLastId() != null && productMaterialEditorVO.getLastId() != 0) {
            idxNum = productMaterialEditorVO.getLastId() + 1;
        }

        List<TProductMaterial> tProductMaterials = productMaterialService.list(new LambdaQueryWrapper<TProductMaterial>()
                .eq(TProductMaterial::getProductId, productMaterialEditorVO.getProductId())
                .eq(TProductMaterial::getType, productMaterialEditorVO.getType())
                .eq(TProductMaterial::getStatus, IsDeleteEnum.NORMAL.getCode())
                .gt(TProductMaterial::getIdxNum, productMaterialEditorVO.getLastId()));
        if (!CollectionUtils.isEmpty(tProductMaterials)) {
            tProductMaterials.forEach(f -> {
                f.setIdxNum(f.getIdxNum() + 1);
                productMaterialService.updateById(f);
            });
        }
        productMaterial.setIdxNum(idxNum);
        productMaterialService.save(productMaterial);


        return Result.OK();
    }

    /**
     * 查询详情
     *
     * @param id
     * @return
     */
    public Result<ProductMaterialDTO> queryMaterialDetailByPrimary(Long id) {
        TProductMaterial productMaterial = productMaterialService.getById(id);
        Optional.ofNullable(productMaterial).orElseThrow(() -> new JeecgBootException("查询资料详情异常"));
        ProductMaterialDTO productMaterialDTO = new ProductMaterialDTO();
        BeanUtils.copyProperties(productMaterial, productMaterialDTO);
        return Result.OK(productMaterialDTO);
    }


    /**
     * 删除资料
     *
     * @param id
     * @return
     */
    public Result<?> deleteProductMaterial(Long id) {
        TProductMaterial productMaterial = productMaterialService.getById(id);
        if (ObjectUtil.isEmpty(productMaterial) || productMaterial.getStatus() == IsDeleteEnum.DELETE.getCode()) {
            throw new JeecgBootException("资料不存在");
        }
        productMaterial.setStatus(IsDeleteEnum.DELETE.getCode());
        boolean flag = productMaterialService.updateById(productMaterial);
        if (flag) {
            materialLinkedService.remove(new LambdaQueryWrapper<TMaterialLinked>()
                    .eq(TMaterialLinked::getMaterialId, productMaterial.getId()));
            syncModifyMaterialIdxNum(productMaterial);
            return Result.OK();
        }
        return Result.error("删除资料失败");
    }

    /**
     * 更新排序
     *
     * @param productMaterial
     */
    private void syncModifyMaterialIdxNum(TProductMaterial productMaterial) {
        List<TProductMaterial> productMaterials = productMaterialService.list(new LambdaQueryWrapper<TProductMaterial>()
                .eq(TProductMaterial::getProductId, productMaterial.getProductId())
                .eq(TProductMaterial::getType, productMaterial.getType())
                .eq(TProductMaterial::getStatus, IsDeleteEnum.NORMAL.getCode()));
        if (CollectionUtils.isEmpty(productMaterials)) {
            return;
        }
        productMaterials.stream()
                .filter(f -> f.getIdxNum() > productMaterial.getIdxNum())
                .forEach(m -> {
                    m.setIdxNum(m.getIdxNum() - 1);
                    productMaterialService.updateById(m);
                });
    }
}